<script lang="ts">
  import {
    DRAW_ORDER_BY_CREATE,
    get_draw,
    list_draw,
    remove_draw,
    update_draw_basic,
    type DrawInfo,
  } from "$lib/api/board/board_draw";
  import RemoveModal from "$lib/components/modal/RemoveModal.svelte";
  import { boardStore } from "$lib/stores/board.svelte";
  import { userStore } from "$lib/stores/user.svelte";
  import { request } from "$lib/utils/request";
  import { Pagination } from "@skeletonlabs/skeleton-svelte";
  import type { Store as ToastStore } from "@zag-js/toast";
  import dayjs from "dayjs";
  import { getContext } from "svelte";
  import IconArrowLeft from "lucide-svelte/icons/arrow-left";
  import IconArrowRight from "lucide-svelte/icons/arrow-right";
  import IconEllipsis from "lucide-svelte/icons/ellipsis";
  import IconFirst from "lucide-svelte/icons/chevrons-left";
  import IconLast from "lucide-svelte/icons/chevron-right";
  import EditText from "$lib/components/editable/EditText.svelte";
  import { openBoardDrawWindow } from "$lib/utils/window";
  import ViewDrawPermModal from "$lib/components/modal/board/draw/ViewDrawPermModal.svelte";
  import { listen } from "@tauri-apps/api/event";
  import type { AllNotice, board as board_notice } from "$lib/api/notice_type";

  const toast: ToastStore = getContext("toast");

  const PAGE_SIZE = 20;

  let drawList = $state([] as DrawInfo[]);
  let totalCount = $state(0);
  let curPage = $state(0);

  let hoverDrawId = $state("");
  let removeDrawInfo = $state(null as null | DrawInfo);
  let viewPermDrawInfo = $state(null as null | DrawInfo);

  let drawVersion = $state(0);

  async function loadDrawList() {
    const res = await request(
      list_draw({
        session_id: userStore.userSession,
        board_id: boardStore.curBoardId,
        order_by: DRAW_ORDER_BY_CREATE,
        offset: curPage * PAGE_SIZE,
        limit: PAGE_SIZE,
      })
    );
    drawList = res.draw_list;
    totalCount = res.total_count;
  }

  async function removeDraw() {
    if (removeDrawInfo == null) {
      return;
    }
    await request(
      remove_draw({
        session_id: userStore.userSession,
        board_id: boardStore.curBoardId,
        draw_id: removeDrawInfo.draw_id,
      })
    );
    await loadDrawList();
    toast.create({
      title: "成功",
      description: "删除画稿成功!",
      type: "success",
    });
    removeDrawInfo = null;
  }

  async function onUpdateDraw(drawId: string) {
    const tmpList = drawList.slice();
    const index = tmpList.findIndex((item) => item.draw_id == drawId);
    if (index == -1) {
      return;
    }
    const res = await request(
      get_draw({
        session_id: userStore.userSession,
        board_id: boardStore.curBoardId,
        draw_id: drawId,
      })
    );
    tmpList[index] = res.draw;
    drawList = tmpList;
  }

  async function updateDrawName(
    drawId: string,
    newName: string
  ): Promise<boolean> {
    if (newName.trim() == "") {
      return false;
    }
    await request(
      update_draw_basic({
        session_id: userStore.userSession,
        board_id: boardStore.curBoardId,
        draw_id: drawId,
        basic_info: {
          draw_name: newName.trim(),
        },
      })
    );
    await onUpdateDraw(drawId);
    return true;
  }

  async function processBoardNotice(notice: board_notice.AllNotice) {
    if (notice.UpdateDrawNotice != undefined) {
      await onUpdateDraw(notice.UpdateDrawNotice.draw_id);
    } else if (notice.RemoveDrawNotice != undefined) {
      if (
        drawList.findIndex(
          (item) => item.draw_id == notice.RemoveDrawNotice?.draw_id
        ) != -1
      ) {
        await loadDrawList();
      }
    }
  }

  $effect(() => {
    if (userStore.userSession != "" && boardStore.drawVersion != drawVersion) {
      loadDrawList();
    }
  });

  $effect(() => {
    if (userStore.userSession != "" && boardStore.drawVersion != drawVersion) {
      drawVersion = boardStore.drawVersion;
      curPage = 0;
      loadDrawList();
    }
  });

  $effect(() => {
    const unListen = listen<AllNotice>("notice", (ev) => {
      const payload = ev.payload;
      if (payload.BoardNotice != undefined) {
        processBoardNotice(payload.BoardNotice);
      }
    });
    return () => {
      unListen.then((fn) => fn());
    };
  });
</script>

<div class="h-[calc(100vh-100px)] overflow-y-auto p-2">
  <div class="table-wrap">
    <table class="table">
      <thead>
        <tr>
          <th>名称</th>
          <th class="w-[100px]">节点数量</th>
          <th class="w-[100px]">连线数量</th>
          <th class="w-[100px]">创建时间</th>
          <th class="w-[100px]">最后更新</th>
          <th class="w-[230px]">操作</th>
        </tr>
      </thead>
      <tbody>
        {#each drawList as draw}
          <tr
            class="hover:preset-tonal h-[50px]"
            onmouseenter={() =>
              setTimeout(() => {
                hoverDrawId = draw.draw_id;
              }, 100)}
            onmouseleave={() => (hoverDrawId = "")}
          >
            <td>
              <EditText
                value={draw.basic_info.draw_name}
                canEdit={boardStore.curWebBoard?.myMember?.admin == true}
                maxWidthClass="max-w-[calc(100vw-900px)]"
                onChange={(newValue) => updateDrawName(draw.draw_id, newValue)}
                onClick={() =>
                  openBoardDrawWindow(
                    boardStore.curBoardId,
                    draw.draw_id
                  )}
              />
            </td>
            <td>{draw.node_count}</td>
            <td>{draw.edge_count}</td>
            <td>{dayjs(draw.create_time).format("YYYY-MM-DD")}</td>
            <td>{dayjs(draw.update_time).format("YYYY-MM-DD")}</td>
            <td class="flex gap-2">
              <button
                type="button"
                class="btn p-0"
                onclick={() =>
                  openBoardDrawWindow(
                    boardStore.curBoardId,
                    draw.draw_id
                  )}>打开</button
              >
              <button
                type="button"
                class="btn p-0"
                onclick={() => (viewPermDrawInfo = draw)}>查看权限</button
              >
              {#if hoverDrawId == draw.draw_id && boardStore.curWebBoard?.myMember?.admin == true}
                <button
                  type="button"
                  class="btn preset-filled-error-200-800"
                  onclick={() => (removeDrawInfo = draw)}>删除</button
                >
              {/if}
            </td>
          </tr>
        {/each}
      </tbody>
    </table>
  </div>
  <div class="mt-2 flex justify-end mr-4">
    <Pagination
      data={drawList}
      count={totalCount}
      page={curPage + 1}
      pageSize={PAGE_SIZE}
      buttonClasses="rounded-none"
      onPageChange={(value) => {
        curPage = value.page - 1;
        loadDrawList();
      }}
    >
      {#snippet labelEllipsis()}<IconEllipsis class="size-4" />{/snippet}
      {#snippet labelNext()}<IconArrowRight class="size-4" />{/snippet}
      {#snippet labelPrevious()}<IconArrowLeft class="size-4" />{/snippet}
      {#snippet labelFirst()}<IconFirst class="size-4" />{/snippet}
      {#snippet labelLast()}<IconLast class="size-4" />{/snippet}
    </Pagination>
  </div>
</div>

<div class="absolute -left-[10000px]">
  {#if removeDrawInfo != null}
    <RemoveModal
      title="删除画稿"
      content={`是否删除画稿 ${removeDrawInfo.basic_info.draw_name} ?`}
      onCancel={() => (removeDrawInfo = null)}
      onOk={() => removeDraw()}
    />
  {/if}
  {#if viewPermDrawInfo != null}
    <ViewDrawPermModal
      boardId={boardStore.curBoardId}
      drawInfo={viewPermDrawInfo}
      canEdit={boardStore.curWebBoard?.myMember?.admin == true}
      onClose={() => (viewPermDrawInfo = null)}
    />
  {/if}
</div>
